#!/usr/bin/env python
#! coding: utf-8
#! python3
# Pone and Watch
# A dirty, small game, coded in a week for the 2023 /mlp/ summer game jam (post 40053734)
# The code is awefully dirty. Please don't use this to learn...

import pygame


# Display abstraction
class lcd():
	blink = False
	blinkCpt = 30
	
	img_bck = None
	img_lcd = None
	fullDisplay = False
	
	score = 0
	mare = [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0]]
	mareBlink = False
	marePosition = 2
	mareAttack = False
	mareDefence = False
	img_digits = False
	
	monsterState = [-1,-1,-1,-1]
	batState = [-1,-1]
	
	def __init__( self ):
		self.score = 0
		
		self.img_bck = pygame.image.load( r"img\background.png" )
		self.img_lcd = pygame.image.load( r"img\lcd.png" )
		
		self.img_digits = pygame.image.load( r"img\digits.png" )
		self.img_mare = pygame.image.load( r"img\mare.png" )
		self.img_mare_coords =[
[ ((44,133),((0,0),(58,50))), ((84,113),((59,0),(50,54))), ((136,92),((110,0),(42,72))), ((186,113),((153,0),(50,54))), ((218,133),((204,0),(58,50)))],
[ ((44,133),((0,73),(58,50))), ((84,113),((59,73),(50,54))), ((136,92),((110,73),(42,72))), ((186,113),((153,73),(50,54))), ((218,133),((204,73),(58,50)))],
[ ((44,133),((0,146),(58,50))), ((84,113),((59,146),(50,54))), ((136,92),((110,146),(42,72))), ((186,113),((153,146),(50,54))), ((218,133),((204,146),(58,50)))]
]
		self.img_monsters = pygame.image.load( r"img\monsters.png" )
		self.img_monsters_coords =[
[ ((11,110),((0,0),(49,42))), ((57,85),((50,0),(49,44))), ((214,85),((100,0),(49,44))), ((260,110),((150,0),(49,42)))],
[ ((11,95),((0,43),(49,57))), ((57,70),((50,45),(49,59))), ((214,70),((100,45),(49,59))), ((260,95),((150,43),(49,57)))],
[ ((11,110),((0,101),(49,42))), ((57,85),((50,105),(49,44))), ((214,85),((100,105),(49,44))), ((260,110),((150,101),(49,42)))]
]
		self.img_bats_coords =[
[ ((3,70),((0,144),(20,11))), ((15,99),((0,144),(20,11))), ((53,117),((0,144),(20,11))), ((109,171),((0,144),(20,11)))],
[ ((297,70),((21,144),(20,11))), ((285,99),((21,144),(20,11))), ((247,117),((21,144),(20,11))), ((191,171),((21,144),(20,11)))]
]
	
	def fullDisplay_set( self, fullDisplay=False ):
		self.fullDisplay = fullDisplay
	
	def score_set( self, value=0 ):
		self.score = score
	
	def monster_set_state( self, monsterState=(-1,-1,-1,-1) ):
		self.monsterState = monsterState
	
	def bat_set_state( self, batState=(-1,-1) ) :
		self.batState = batState
	
	def mare_set_state( self, position, attack=False, defence=False, blink=False ):
		
		# Sanitize input
		if( position < 0 ) : position = 0
		if( position > 4 ) : position = 4
		
		# Update internal state
		for i in range(5) :
			self.mare[0][i] = False
			self.mare[1][i] = False
			self.mare[2][i] = False
		
		self.mare[0][position] = True
		self.mare[1][position] = attack
		self.mare[2][position] = defence
		self.mareBlink = blink
		self.mareAttack = attack
		self.marePosition = position
		self.mareDefence = defence
	
	def display( self, target ):
		
		# Background
		target.blit( self.img_bck, (0,0) )
		
		if self.fullDisplay :
			if( self.blink ) :
				target.blit( self.img_lcd, (0,0) )
			
		else :
			
			# Dirty display
			# Mare
			if self.mareAttack: state = 1
			elif self.mareDefence: state = 2
			else: state = 0
			index = self.marePosition
			target.blit( self.img_mare, self.img_mare_coords[state][index][0], self.img_mare_coords[state][index][1] )
			
			# Monsters display
			for index in range(len(self.monsterState)) :
				if self.monsterState[index] >= 0 :
					target.blit( self.img_monsters, self.img_monsters_coords[self.monsterState[index]][index][0], self.img_monsters_coords[self.monsterState[index]][index][1] )
			
			for index in range(len(self.batState)) :
				if self.batState[index] >= 0 :
					target.blit( self.img_monsters, self.img_bats_coords[index][self.batState[index]][0], self.img_bats_coords[index][self.batState[index]][1] )
			
			# Score display
			num = f"{self.score:05}"
			for i in range(5) :
				digit = int(num[i])
				target.blit( self.img_digits, (3+(27*i),196), (((23*digit),0), (23,41)) )
		
		# Update blink counter
		if( self.blinkCpt > 1 ) :
			self.blinkCpt -= 1
		else:
			self.blink = not self.blink
			self.blinkCpt = 30


# Mare!
class mare():
	position = 2
	attack = False
	defence = False
	sick = False
	sfx_move = None
	status_cpt = 0
	
	def __init__( self, position=2, attack=False, defence=False, sick=False ):
		self.position = position
		self.attack = attack
		self.defence = defence
		self.sick = sick
		status_cpt = 0
	
	def set_sfx( self, sfx_move=None ):
		self.sfx_move = sfx_move
	
	def set_attack( self, attack=True ):
		self.attack = attack
		if attack: self.defence = False
		self.status_cpt = 30
	
	def set_defence( self, defence=True ):
		self.defence = defence
		if defence: self.attack = False
		self.status_cpt = 30
	
	def move( self, amount=0 ):
		if( amount>0 ):
			if( self.position<4 ):
				self.position += 1
				self.sfx_move.play()
		elif( amount<0 ):
			if( self.position>0 ):
				self.position -= 1
				self.sfx_move.play()
				
	
	def step( self ):
		if self.status_cpt > 0 : self.status_cpt -= 1
		
		if self.status_cpt == 0 :
			self.attack = False
			self.defence = False


# Housekeeping
if __name__ != "__main__" :
	print( "Can't be called from external script!" )
	#return 1


# Init
screenResolution = (320,240)
gameResolution = (320,240)
pygame.init()
screen = pygame.display.set_mode( screenResolution, flags=pygame.RESIZABLE|pygame.SCALED )
display = pygame.Surface( gameResolution )

framerate = 60
timer = pygame.time.Clock()

pygame.mixer.init()

# Game vars
score = 0

# Ressource loading
sfx_theme = pygame.mixer.Sound( r"sfx\theme.wav" )
sfx_move = pygame.mixer.Sound( r"sfx\move_low.wav" )

lcd = lcd()
mare = mare( 2, False, False, False )
mare.set_sfx( sfx_move )

# Intro
gameState = "intro"
sfx_theme.play()


# Main loop
running = True
while running:
	
	#----------
	# Begin step
	
	#----------
	# Events
	for event in pygame.event.get() :
		if event.type == pygame.QUIT :
			running = False
			
		
		if gameState == "game" :
			if event.type == pygame.KEYDOWN :
				if event.key == pygame.K_ESCAPE :
					running = False
					
				if event.key == pygame.K_LEFT :
					mare.move( -1 )
				
				if event.key == pygame.K_RIGHT :
					mare.move( 1 )
				
				if event.key == pygame.K_SPACE :
					mare.set_attack()
					score += 1
				
				if event.key == pygame.K_LCTRL :
					mare.set_defence()
					score += 10
				
		elif gameState == "intro" :
			if event.type == pygame.KEYDOWN :
				sfx_theme.stop()
				# gameState = "game"
	
	#----------
	# Step
	
	if gameState == "game" :
		mare.step()
		
		if score > 99999 : score = 99999
		
	elif gameState == "intro" :
		lcd.fullDisplay_set( True )
		
		if not pygame.mixer.get_busy() :
			gameState = "game"
			lcd.fullDisplay_set( False )
	
	#----------
	# Draw
	if gameState == "game" :
		lcd.mare_set_state( mare.position, mare.attack, mare.defence )
		lcd.score_set( score )
		
		lcd.monster_set_state( (-1,-1,-1,-1) )
		lcd.bat_set_state( (-1,-1) )
	
	elif gameState == "intro" :
		pass
		
	
	lcd.display( display )
	
	#----------
	screen.blit( pygame.transform.scale( display, screenResolution ), (0,0) )
	pygame.display.flip()
	timer.tick( framerate )
	

pygame.quit()
